
Ext.define('FrontSuite.controller.Application', {
    extend: 'Ext.app.Controller',

    tabTimeCreatedCache : {},
    msgContainer : null,

    init: function () {
        FrontSuite.app = this;
    },
    
    isViewableTreeId: function (id) {
        var arrayId = id.split('.');
        var viewable = false;
        if (arrayId.length >= 2) {
            viewable = true;
        }
        return(viewable);
    },
    
    addTab: function (tabId) {
        var firstTime = 0;
        if (!this.tabTimeCreatedCache[tabId]) {
            firstTime = 1;
            this.tabTimeCreatedCache[tabId] = new Date();
        }

        var t = new Date();
        var secondsDiff = (t - this.tabTimeCreatedCache[tabId]) / 1000;
        if (firstTime || secondsDiff > 90) {
            this.tabTimeCreatedCache[tabId] = t;
            var obj = this;

            var tabPanel  = Ext.getCmp('vp-region-tabpanel');

            if (Ext.getCmp(tabId) === undefined) {
                var tabIdPart = tabId.split('.');
                if      (tabIdPart.length == 0) { FrontSuite.app.error({message: 'Error: unrecognized tabId ('+tabId+')'}); }
                else if (tabIdPart.length == 1) { // e.g. 'SampleDashboard'
                    var view = Ext.create('FrontSuite.view.'+tabIdPart[0], 'view-'+tabIdPart[0]);
                    tabPanel.add({
                        title      : tabIdPart[0],
                        closable   : true,
                        id         : tabId,
                        layout     : 'fit',
                        items      : [ view ],
                        listeners  : {
                            close  : function() {
                                if (Ext.getCmp(tabId) != null) {
                                    Ext.getCmp('accordion-info-panel').remove(Ext.getCmp('info-panel-' + tabId));
                                    obj.tabTimeCreatedCache[tabId] = null;
                                }
                            }
                        }
                    });
                    tabPanel.setActiveTab(tabId);

                    // create and show the view info
                    var info = Ext.getCmp('accordion-info-panel');
                    var viewInfo = Ext.create('FrontSuite.view.ViewInfo', tabId, viewDef);
                    info.add(viewInfo);
                    viewInfo.expand();
                }
                else if (tabIdPart.length == 2 && tabIdPart[1] == 'html') {
                    tabPanel.add({
                        title      : tabIdPart[0],
                        closable   : true,
                        id         : tabId,
                        layout     : 'fit',
                        items      : [{
                            styleHtmlContent: true,
                            autoScroll: true,
                            style         : {
                                'font-size': 14
                            },
                            loader: {
                                url: 'html/'+tabIdPart[0]+'.html',
                                autoLoad: true
                            }
                        }],
                        listeners  : {
                            close  : function() {
                                if (Ext.getCmp(tabId) != null) {
                                    obj.tabTimeCreatedCache[tabId] = null;
                                }
                            }
                        }
                    });
                    tabPanel.setActiveTab(tabId);
                }
                else { // e.g. tiber6.mvh.geo_airport or tiber6.mvh.geo_airport.country_summary
                    FrontSuite.db.getTableDef({
                        tabid: tabId,
                        success: function (tabId, viewDef) {

                            // in the future, we will have different kinds of views. Some are grids, others compound dashboards, but for now, it's just a grid
                            // create and show the grid
                            var grid = Ext.create('FrontSuite.view.Grid', {tabId: tabId, viewDef: viewDef});

                            var grid_extra = Ext.create('Ext.tab.Panel', {
                                id: tabId+'-xpanel',
                                xtype: 'tabpanel',
                                items: [
                                   {
                                     title: 'Hello',
                                     html:  'hello',
                                     columnWidth: 0.70
                                   },
                                   {
                                     title: 'World',
                                     html:  'world',
                                     columnWidth: 0.30
                                   }
                                ]
                            });

                            var tabPanel = Ext.getCmp('vp-region-tabpanel');

                            tabPanel.add({
                                title      : viewDef.table_label,
                                closable   : true,
                                id         : tabId,
                                // layout     : 'column',
                                // items      : [ grid, grid_extra ],
                                layout     : 'fit',
                                items      : [ grid ],
                                listeners  : {
                                    close  : function() {
                                        if (Ext.getCmp(tabId) != null) {
                                            Ext.getCmp('accordion-info-panel').remove(Ext.getCmp('info-panel-' + tabId));
                                            obj.tabTimeCreatedCache[tabId] = null;
                                        }
                                    }
                                }
                            });
                            tabPanel.setActiveTab(tabId);

                            // create and show the view info
                            var info = Ext.getCmp('accordion-info-panel');
                            var viewInfo = Ext.create('FrontSuite.view.ViewInfo', tabId, viewDef);
                            info.add(viewInfo);
                            viewInfo.expand();
                        }
                    });
                }
            }
        }
    },

    refreshTabPanel: function () {
        var tabpanel = Ext.getCmp('vp-region-tabpanel');
    },

    createModalDialog: function (config) {
        var config2 = {
            modal: true,
            closeAction: 'hide',
            resizable: false,
            shadowOffset: 25
        };
        if (config.id)    config2.id    = config.id;
        if (config.title) config2.title = config.title;

        if      (config.panel) config2.items = [config.panel];
        else if (config.items) config2.items = config.items;
        else                   this.error({message: 'No items supplied for modal dialog to display'});

        var dialog = Ext.create("Ext.Window", config2);

        return(dialog);
    },

    createConstantValueLabelStore: function (valid_values, value_labels) {
        var data = [];
        var i, value, label;
        for (i = 0; i < valid_values.length; i++) {
            value = valid_values[i];
            if (value_labels && value_labels[value]) label = value_labels[value];
            else                                     label = value;
            data[i] = {'value': value, 'label': label};
        }
        var store = Ext.create('Ext.data.Store', {
            fields: ['value', 'label'],
            data : data
        });
        return(store);
    },

    createFormFieldConfig: function (columnDef, parentId) {
//console.log('createFormFieldConfig('+columnDef.column_name+')');
        var fieldConfig = {
            name:       columnDef.column_name,
            fieldLabel: columnDef.column_label,
            allowBlank: ((columnDef.not_null_ind == 'Y') ? false : true)
        };

        if      (columnDef.id) fieldConfig.id = columnDef.id;
        else if (parentId) fieldConfig.id = parentId + '-' + columnDef.column_name;

        if (columnDef.not_null_ind == 'Y') {
            fieldConfig.afterLabelTextTpl = '&nbsp;<span style="color: red; font-weight: bold;" data-qtip="This is a required field and cannot be left blank">*</span>';
        }
        if (columnDef.help) {
            // fieldConfig.afterBodyEl = '&nbsp;<span data-qtip="' + columnDef.help + '"><img src="" style="width: 15px; height: 15px;" class="x-tool-help"></span>';
//console.log(fieldConfig);
        }
        // form field xtypes: textfield, numberfield, hiddenfield, datefield, filefield, radiofield, textareafield, htmleditor
        if (columnDef.valid_values) {
            fieldConfig.xtype          = 'combo';
            fieldConfig.store          = this.createConstantValueLabelStore(columnDef.valid_values, columnDef.value_labels);
            fieldConfig.queryMode      = 'local';
            fieldConfig.displayField   = 'value';
            fieldConfig.valueField     = 'label';
            fieldConfig.forceSelection = true;
        }
        else if (!columnDef.column_type) {
            fieldConfig.xtype = 'textfield';
            if (columnDef.display_option) {
                if      (columnDef.display_option == 'password') fieldConfig.inputType = 'password';
                else if (columnDef.display_option == 'hidden')   fieldConfig.xtype     = 'hiddenfield';
                else if (columnDef.display_option == 'readonly') { fieldConfig.readOnly = true; fieldConfig.hideTrigger = true; }
            }
        }
        else if (columnDef.column_type == 'date') {
            fieldConfig.xtype = 'datefield';
            fieldConfig.format = 'Y-m-d';
            fieldConfig.altformat = 'm/d/Y|m.d.Y|m,d,Y';
        }
        else if (columnDef.column_type == 'datetime') {
            fieldConfig.xtype = 'datefield';
            fieldConfig.format = 'Y-m-d H:i:s';
            fieldConfig.altformat = 'm/d/Y|m.d.Y|m,d,Y';
        }
        else if (columnDef.column_type == 'float') {
            fieldConfig.xtype = 'numberfield';
        }
        else if (columnDef.column_type == 'integer') {
            fieldConfig.xtype = 'numberfield';
            fieldConfig.allowDecimals = false;
        }
        else if (columnDef.column_type == 'text') {
            fieldConfig.xtype = 'textareafield';
            fieldConfig.grow = true;
        }
        else if (columnDef.column_type == 'separator') {
            fieldConfig.xtype = '???';  // not sure what this one is yet
        }
        else {  // columnDef.column_type == 'string'
            fieldConfig.xtype = 'textfield';
            if (columnDef.display_option) {
                if      (columnDef.display_option == 'password') fieldConfig.inputType = 'password';
                else if (columnDef.display_option == 'hidden')   fieldConfig.xtype     = 'hiddenfield';
                else if (columnDef.display_option == 'readonly') { fieldConfig.readOnly = true; fieldConfig.hideTrigger = true; }
            }
        }
        if (columnDef.default) {
            fieldConfig.value = columnDef.default;
        }
        //if (columnDef.valid_values && fieldConfig.xtype == 'textfield') {
        //    var regex_str = '^(' + columnDef.valid_values.join('|') + ')$';
        //    var regex_msg = 'The field must contain one of the following values: ' + columnDef.valid_values.join(', ') + '.';
        //    var regex     = new RegExp(regex_str);
        //    fieldConfig.regex = regex;
        //    fieldConfig.regexText = regex_msg;
        //}
        return(fieldConfig);
    },

    createFormFieldsFromColumnDefs: function (columnDefs, columns, parentId) {
        var i, column, items = [];
        for (i = 0; i < columns.length; i++) {
            column = columns[i];
            if (columnDefs[column]) {
                items[i] = this.createFormFieldConfig(columnDefs[column], parentId);
            }
            else FrontSuite.app.error({object: 'Application', method: 'createFormPanelFromTableDef', message: 'Column ['+column+'] does not exist in table ['+tableDef.table_name+']'});
        }
        return(items);
    },

    createFormPanelFromTableDef: function (tableDef, columns, submitHandler, parentId) {

        if (columns == null) columns = tableDef.columns;
        var columnDefs = tableDef.column;
        var items = this.createFormFieldsFromColumnDefs(columnDefs, columns, parentId);

        var cancelButton = { text: 'Cancel', handler: function (btn) { btn.up('window').hide(); } };
        var submitButton = { text: 'Submit' };
        if (submitHandler) submitButton.handler = submitHandler;

        var form = Ext.create("Ext.form.Panel", {
            frame: false,
            resizable: false,
            bodyStyle:'padding:5px 5px 0',
            width: 350,
            // height: 400,
            autoScroll: true,
            fieldDefaults: {
                msgTarget: 'side',
                labelWidth: 100
            },
            border: false,
            defaultType: 'textfield',
            defaults: {
                anchor: '100%'
            },

            items: items,

            buttons: [
                submitButton,
                cancelButton
            ]
        });
        return(form);
    },

    // a utility method used by the msg() method
    _createMsgBox: function (title, messageText){
       // return ['<div class="msg">',
       //         '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
       //         '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3>', title, '</h3>', messageText, '</div></div></div>',
       //         '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
       //         '</div>'].join('');
       return '<div class="msg"><h3>' + title + '</h3><p>' + messageText + '</p></div>';
    },

    // code based on http://dev.sencha.com/deploy/ext-4.0.0/examples/message-box/msg-box.html
    message: function (title, messageText) {   // extra arguments after the messageText get substituted into messageText e.g. 'You clicked the {0} button and entered the text "{1}".'
        if (!this.msgContainer) {
            this.msgContainer = Ext.core.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
        }
        var formattedMessageText = Ext.String.format.apply(String, Array.prototype.slice.call(arguments, 1));   // substitute extra args into messageText
        var msgElement = Ext.core.DomHelper.append(this.msgContainer, this._createMsgBox(title, formattedMessageText), true);
        msgElement.hide();
        msgElement.slideIn('t').ghost("t", { delay: 1500, remove: true});
    },

    // args = { object: xxx, id: xxx, method: xxx, message: xxx, sysmessage: xxx }
    error: function (args) {
        var message;
        if (Ext.isString(args)) message = args;
        else                    message = args.message;
        if (!message) {
            Ext.MessageBox.show({
                title   : 'Error',
                msg     : 'Error: An error occurred with no error message',
                buttons : Ext.MessageBox.OK
            });
        }
        else if (message.indexOf("\n") > -1) {
            Ext.create("Ext.Window", {
                title   : 'Error Status',
                modal   : true,
                width   : 350,
                layout  : 'fit',
                autoShow : true,
                items: [{
                    xtype:    'panel',
                    html:      '<pre>Error: ' + message + '</pre>',
                    autoScroll : true
                }],
                buttons: [
                    { text: 'OK', handler: function (btn) { btn.up('window').destroy(); } }
                ],
                tools: [
                    { type: 'maximize', handler: function (event, toolEl, owner, tool) { tool.up('window').maximize(); } },
                    { type: 'restore',  handler: function (event, toolEl, owner, tool) { tool.up('window').restore();  } }
                ]
            });
        }
        else {
            Ext.MessageBox.show({
                title   : 'Error',
                msg     : message,
                buttons : Ext.MessageBox.OK
            });
        }
    },

    // args = { object: xxx, id: xxx, method: xxx, message: xxx, sysmessage: xxx }
    notify: function (args) {
        var message;
        if (Ext.isString(args)) message = args;
        else                    message = args.message;
        Ext.MessageBox.show({
            title   : 'Notification',
            msg     : message,
            buttons : Ext.MessageBox.OK
        });
    }
});

